package org.jeecg.modules.online.cgform.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.online.cgform.components.LinkDown;
import org.jeecg.modules.online.cgform.entity.OnlCgformButton;
import org.jeecg.modules.online.cgform.entity.OnlCgformEnhanceJs;
import org.jeecg.modules.online.cgform.entity.OnlCgformField;
import org.jeecg.modules.online.cgform.entity.OnlCgformHead;
import org.jeecg.modules.online.cgform.enums.CgformConstant;
import org.jeecg.modules.online.cgform.model.*;
import org.jeecg.modules.online.cgform.service.IOnlCgformFieldService;
import org.jeecg.modules.online.cgform.service.IOnlCgformHeadService;
import org.jeecg.modules.online.cgform.service.IOnlineService;
import org.jeecg.modules.online.cgform.util.CgformUtil;
import org.jeecg.modules.online.cgform.util.EnhanceJsUtil;
import org.jeecg.modules.online.cgform.util.OnlFormShowType;
import org.jeecg.modules.online.cgform.util.OnlSlotRender;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("onlineService")
public class OnlineServiceImpl implements IOnlineService {

    @Autowired
    private IOnlCgformFieldService onlCgformFieldService;

    @Autowired
    private IOnlCgformHeadService onlCgformHeadService;

    @Autowired
    private ISysBaseAPI sysBaseAPI;


    @Override
    public OnlComplexModel queryOnlineConfig(OnlCgformHead head) {
        String headId = head.getId();
        //1.查询字段集合
        List<OnlCgformField> fieldList = getListColumns(headId);
        //2.查询需要被隐藏的列
        List<String> hideColumns = onlCgformFieldService.selectOnlineHideColumns(head.getTableName());
        //3.定义列
        List<OnlColumn> columns = new ArrayList<OnlColumn>();
        //4.定义字典配置
        Map<String, List<DictModel>> dictOptions = new HashMap<String, List<DictModel>>();
        // 定义 href插槽集合
        List<HrefSlots> fieldHrefSlots = new ArrayList<HrefSlots>();
        // 定义外键配置
        List<OnlForeignKey> foreignKeys = new ArrayList<OnlForeignKey>();
        List<String> excludeList = new ArrayList<String>();
        //5.遍历
        for (OnlCgformField item : fieldList) {
            String dbFieldName = item.getDbFieldName();

            //如果当前列是外键
            String mainTable = item.getMainTable();
            String mainField = item.getMainField();
            if(oConvertUtils.isNotEmpty(mainField) && oConvertUtils.isNotEmpty(mainTable)){
                OnlForeignKey foreignKey = new OnlForeignKey(dbFieldName,mainField);
                foreignKeys.add(foreignKey);
            }

            //排除不显示的列
            if(CgformUtil.SHOW_LIST_YES!=item.getIsShowList()){
                continue;
            }

            //id 不显示
            if(CgformUtil.COLUMN_ID.equals(dbFieldName)) {
                continue;
            }
            // 如果隐藏的列
            if(hideColumns.contains(dbFieldName)) {
                continue;
            }

            if(excludeList.contains(dbFieldName)){
                continue;
            }

            OnlColumn column = new OnlColumn(item.getDbFieldTxt(),dbFieldName);
            String dictCode = item.getDictField();
            String view = item.getFieldShowType();
            //TODO A.抽象以下逻辑 按对象处理是否好点 B.那个字典数据的加载是否应该放在前端
            if(oConvertUtils.isNotEmpty(dictCode) && !"popup".equals(view)) {
                List<DictModel> ls = new ArrayList<DictModel>();
                //普通字典 + 表字典
                if(oConvertUtils.isNotEmpty(item.getDictTable())) {
                    ls = sysBaseAPI.queryTableDictItemsByCode(item.getDictTable(), item.getDictText(), dictCode);
                }else if(oConvertUtils.isNotEmpty(item.getDictField())) {
                    ls = sysBaseAPI.queryDictItemsByCode(dictCode);
                }
                dictOptions.put(dbFieldName,ls);
                column.setCustomRender(dbFieldName);
            }

            if(CgformUtil.LINK_DOWN.equals(view)){
                String jsonStr = item.getDictTable();
                LinkDown json = JSONObject.parseObject(jsonStr, LinkDown.class);
                List<DictModel> ls = sysBaseAPI.queryTableDictItemsByCode(json.getTable(), json.getTxt(), json.getKey());
                dictOptions.put(dbFieldName,ls);
                column.setCustomRender(dbFieldName);
                columns.add(column);

                String linkField = json.getLinkField();
                initOtherLinkFields(fieldList,excludeList,columns,dbFieldName,linkField);
            }

            if(CgformUtil.SEL_TREE.equals(view)) {
                //树控件
                String[] colsInfo = item.getDictText().split(CgformUtil.SQL_COMMA);
                List<DictModel> ls  = sysBaseAPI.queryTableDictItemsByCode(item.getDictTable(), colsInfo[2], colsInfo[0]);
                dictOptions.put(dbFieldName,ls);
                column.setCustomRender(dbFieldName);
            }

            if(CgformUtil.CAT_TREE.equals(view)) {
                //分类字典树控件
                String dictText = item.getDictText();
                if(oConvertUtils.isEmpty(dictText)){
                    //只存了id 需要在前端翻译
                    String filterSql = CgformUtil.getSysCatgoryCondition(item.getDictField());
                    List<DictModel> ls  = sysBaseAPI.queryFilterTableDictInfo(CgformUtil.CATEGORY_TABLE_NAME, CgformUtil.CATEGORY_TEXT_NAME, CgformUtil.CATEGORY_ID_NAME,filterSql);
                    dictOptions.put(dbFieldName,ls);
                    column.setCustomRender(dbFieldName);
                }else{
                    //否则直接显示 该text
                    column.setCustomRender( "_replace_text_"+dictText);
                }
            }

            //部门选择也走字典加载
            if("sel_depart".equals(view)) {
                List<DictModel> ls = sysBaseAPI.queryAllDepartBackDictModel();
                dictOptions.put(dbFieldName,ls);
                column.setCustomRender(dbFieldName);
            }

            //用户选择也走字典加载 若用户选择器 选择值改为username显示值为realname 则需要放开以下代码
			if("sel_user".equals(item.getFieldShowType())) {
				List<DictModel> ls = sysBaseAPI.queryTableDictItemsByCode(CgformUtil.USER_TABLE_NAME,CgformUtil.USER_REAL_NAME,CgformUtil.USER_LOGIN_NAME);
				dictOptions.put(dbFieldName,ls);
                column.setCustomRender(dbFieldName);
			}

            //判断文件
            if(view.indexOf(OnlFormShowType.file)>=0) {
                column.setScopedSlots(new ScopedSlots(OnlSlotRender.file));
            }else if(view.indexOf(OnlFormShowType.img)>=0) {
                column.setScopedSlots(new ScopedSlots(OnlSlotRender.img));
            }else if(view.indexOf(OnlFormShowType.editor)>=0) {
                column.setScopedSlots(new ScopedSlots(OnlSlotRender.html));
            }else if(view.equals(OnlFormShowType.date)) {
                column.setScopedSlots(new ScopedSlots(OnlSlotRender.date));
            }else if(view.equals(OnlFormShowType.pca)){
                column.setScopedSlots(new ScopedSlots(OnlSlotRender.pca));
            }
            // 判断是否填写了 href
            if (StringUtils.isNotBlank(item.getFieldHref())) {
                String slotName = OnlSlotRender.hrefPre + dbFieldName;

                column.setHrefSlotName(slotName);
                fieldHrefSlots.add(new HrefSlots(slotName,item.getFieldHref()));
            }
            //支持排序
            if("1".equals(item.getSortFlag())) {
                column.setSorter(true);
            }
            if(!CgformUtil.LINK_DOWN.equals(view)){
                columns.add(column);
            }

        }

        OnlComplexModel model = new OnlComplexModel();
        model.setCode(headId);
        model.setTableType(head.getTableType());
        model.setFormTemplate(head.getFormTemplate());//表单风格
        model.setDescription(head.getTableTxt());//表描述
        model.setCurrentTableName(head.getTableName());//表名
        model.setPaginationFlag(head.getIsPage());//是否分页
        model.setCheckboxFlag(head.getIsCheckbox());//是否checkBox
        model.setScrollFlag(head.getScroll());//是否滚动条

        model.setColumns(columns);
        model.setDictOptions(dictOptions);

        //href插槽
        model.setFieldHrefSlots(fieldHrefSlots);

        //外键
        model.setForeignKeys(foreignKeys);

        //隐藏的列
        model.setHideColumns(hideColumns);

        //自定义button
        List<OnlCgformButton> cgButtonList = this.onlCgformHeadService.queryButtonList(headId,true);
        List<OnlCgformButton> cgFinalBtnList = new ArrayList<OnlCgformButton>();
        for (OnlCgformButton onlCgformButton : cgButtonList) {
            if(hideColumns.contains(onlCgformButton.getButtonCode())) {
                continue;
            }
            cgFinalBtnList.add(onlCgformButton);
        }
        model.setCgButtonList(cgFinalBtnList);

        //JS增强
        OnlCgformEnhanceJs enhanceJs = this.onlCgformHeadService.queryEnhanceJs(headId, CgformUtil.ENHANCE_LIST);
        if(enhanceJs!=null && oConvertUtils.isNotEmpty(enhanceJs.getCgJs())) {
            String enhanceJsStr = EnhanceJsUtil.overFinalWriteJs(enhanceJs.getCgJs(), cgButtonList);
            model.setEnhanceJs(enhanceJsStr);
        }

        //是否树
        if("Y".equals(head.getIsTree())) {
            model.setPidField(head.getTreeParentIdField());
            model.setHasChildrenField(head.getTreeIdField());
            model.setTextField(head.getTreeFieldname());
        }

        return model;
    }

    private void initOtherLinkFields(List<OnlCgformField> fieldList,List<String> excludeList,List<OnlColumn> columns,String customRender,String linkField){
        if(oConvertUtils.isNotEmpty(linkField)){
            String[] arr = linkField.split(",");
            for(String key:arr){
                for(OnlCgformField item:fieldList){
                    String dbFieldName = item.getDbFieldName();
                    //排除不显示的列
                    if(CgformUtil.SHOW_LIST_YES!=item.getIsShowList()){
                        continue;
                    }
                    if(key.equals(dbFieldName)){
                        excludeList.add(key);
                        OnlColumn column = new OnlColumn(item.getDbFieldTxt(),dbFieldName);
                        column.setCustomRender(customRender);
                        columns.add(column);
                        break;
                    }
                }
            }

        }
    }

    @Override
    public JSONObject queryOnlineFormObj(OnlCgformHead head, OnlCgformEnhanceJs onlCgformEnhanceJs) {
        //定义对象
        JSONObject obj = new JSONObject();
        String headId = head.getId();
        //查询有效字段
        List<OnlCgformField> fieldList = this.onlCgformFieldService.queryAvailableFields(head.getId(), head.getTableName(),null, false);
        //查询被禁用字段
        List<String> disabledFieldNameList = this.onlCgformFieldService.queryDisabledFields(head.getTableName());
        //处理JS增强
        EnhanceJsUtil.overwriteJsOneOrMain(onlCgformEnhanceJs, head.getTableName(), fieldList);
        //获取树形配置信息
        TreeSelectColumn treeColumn = null;
        if("Y".equals(head.getIsTree())) {
            treeColumn = new TreeSelectColumn();
            treeColumn.setCodeField("id");
            treeColumn.setFieldName(head.getTreeParentIdField());
            treeColumn.setPidField(head.getTreeParentIdField());
            treeColumn.setPidValue("0");
            treeColumn.setHsaChildField(head.getTreeIdField());
            treeColumn.setTableName(CgformUtil.getRealTableName(head.getTableName()));
            treeColumn.setTextField(head.getTreeFieldname());
        }
        //组装schema
        JSONObject schema = CgformUtil.getJsonSchemaByCgformFieldList(fieldList,disabledFieldNameList,treeColumn);
        schema.put("table",head.getTableName());
        //log.info("----动态表单获取JSON-SCHEMA>>"+schema.toJSONString());
        obj.put("schema", schema);
        //log.info("----动态表单获取JSON-SCHEMA>>"+schema.toJSONString());
        obj.put("head", head);

        //自定义button
        List<OnlCgformButton> cgButtonList = this.onlCgformHeadService.queryButtonList(headId,false);
        if(cgButtonList!=null && cgButtonList.size()>0) {
            obj.put("cgButtonList",cgButtonList);
        }
        //JS增强
        if(onlCgformEnhanceJs!=null && oConvertUtils.isNotEmpty(onlCgformEnhanceJs.getCgJs())) {
            String tempString = EnhanceJsUtil.overwriteClearButton(onlCgformEnhanceJs.getCgJs(), cgButtonList);
            onlCgformEnhanceJs.setCgJs(tempString);
            obj.put("enhanceJs", EnhanceJsUtil.theLastString(onlCgformEnhanceJs.getCgJs()));
        }
        return obj;
    }

    @Override
    public JSONObject queryOnlineFormObj(OnlCgformHead head) {
        OnlCgformEnhanceJs onlCgformEnhanceJs = this.onlCgformHeadService.queryEnhanceJs(head.getId(), CgformUtil.ENHANCE_FORM);
        return queryOnlineFormObj(head,onlCgformEnhanceJs);
    }

    /**
     * 根据表id查询列表显示的列且按OrderNum正序排序
     * @param headId
     * @return
     */
    private List<OnlCgformField> getListColumns(String headId){
        LambdaQueryWrapper<OnlCgformField> query = new LambdaQueryWrapper<OnlCgformField>();
        query.eq(OnlCgformField::getCgformHeadId, headId);
        //query.eq(OnlCgformField::getIsShowList, CgformUtil.SHOW_LIST_YES);
        query.orderByAsc(OnlCgformField::getOrderNum);
        return onlCgformFieldService.list(query);
    }
}
